package com.le.edu.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.le.edu.domain.dto.SubjectDTO;
import com.le.edu.domain.entity.Subject;
import com.le.edu.exception.AppException;
import com.le.edu.resp.ResultCodeEnum;
import com.le.edu.service.SubjectService;
import lombok.extern.slf4j.Slf4j;

import java.util.Objects;

/**
 * @author Le
 * @create 2024-04-07 20:41
 */
@Slf4j
public class SubjectImportListener extends AnalysisEventListener<SubjectDTO> {
    private int successNum = 0;
    private int failureNum = 0;
    private final StringBuilder successMsg = new StringBuilder();
    private final StringBuilder failureMsg = new StringBuilder();
    public SubjectService subjectService;

    public SubjectImportListener() {
    }

    public SubjectImportListener(SubjectService subjectService) {
        this.subjectService = subjectService;
    }

    //一行一行去读取excel内容
    @Override
    public void invoke(SubjectDTO catalogDto, AnalysisContext analysisContext) {
        if (catalogDto == null) {
            throw new AppException("解析Excel失败，在行：" + analysisContext.readRowHolder().getRowIndex() + "数据为空！"
                    , ResultCodeEnum.FAIL.getCode());
        }
        try {
            //添加一级分类
            Subject level1 = existOneSubject(subjectService, catalogDto.getOneSubjectTitle());
            if (Objects.isNull(level1)) {
                level1 = new Subject();
                level1.setPid(0L);
                level1.setTitle(catalogDto.getOneSubjectTitle());
                subjectService.save(level1);
                successNum++;
                successMsg.append("<br/>").append(successNum).append("、一级标题 ").append(level1.getTitle()).append(" 导入成功");
            }
            Long level1Cid = level1.getSubjectId();
            //添加二级分类
            Subject level2 = existTwoSubject(subjectService, catalogDto.getTwoSubjectTitle(), level1Cid);
            if (Objects.isNull(level2)) {
                level2 = new Subject();
                level2.setPid(level1Cid);
                level2.setTitle(catalogDto.getTwoSubjectTitle());
                subjectService.save(level2);
                successNum++;
                successMsg.append("<br/>").append(successNum).append("、二级标题 ").append(level2.getTitle()).append(" 导入成功");
            }
        } catch (Exception e) {
            failureNum++;
            String msg = "<br/>" + failureNum + "、标题 " + catalogDto.getOneSubjectTitle() + "-" + catalogDto.getTwoSubjectTitle() + " 导入失败：";
            failureMsg.append(msg).append(e.getMessage());
            log.error(msg, e);
        }
    }

    //读取完成后执行
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        log.info("数据库导入完成");
    }

    //判断一级分类不能重复添加
    private Subject existOneSubject(SubjectService subjectService, String name) {
        LambdaQueryWrapper<Subject> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Subject::getTitle, name);
        wrapper.eq(Subject::getPid, 0L);
        return subjectService.getOne(wrapper);
    }

    //判断二级分类不能重复添加
    private Subject existTwoSubject(SubjectService subjectService, String name, Long pid) {
        LambdaQueryWrapper<Subject> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Subject::getTitle, name);
        wrapper.eq(Subject::getPid, pid);
        return subjectService.getOne(wrapper);
    }

    public String getAnalysis() {
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new AppException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }
}
